import unittest
from multiprocessing import Process
from multiprocessing import  Lock
from Common.DataHandle import Get_Skip
from threading import Thread
from Common.ReadYaml import ConfigYaml
from Common.Route import Any_Path


class MyProcess(Process):
    def __init__(self, catalog, data):
        '''
        继承多进程，重写该方法
        :param catalog: 目录
        '''
        Process.__init__(self)
        self.catalog = catalog
        self.data = data
        self.lock = Lock()

    def run(self):
        '''
        重写run方法
        :return:
        '''
        testsuite = LoadSuite(self.catalog).load_suite()
        runner = unittest.TextTestRunner(verbosity=1)
        self.lock.acquire()
        result = runner.run(testsuite)
        Get_Skip(result.skipped, self.data).get_skip()
        self.lock.release()



class LoadSuite(object):
    def __init__(self,catalog):
        '''
        封装测试集加载类
        :param catalog: 目录
        '''
        self.catalog = catalog
        self.projectName = ConfigYaml("projectName").base_config
        self.path = Any_Path(self.projectName)
        self.matching = ConfigYaml("matching").base_config

    def load_suite(self):
        '''
        加载测试集
        :return:
        '''
        testsuite = unittest.TestSuite()
        discover = unittest.defaultTestLoader.discover(
            Any_Path(self.projectName,self.catalog),
            pattern=self.matching, top_level_dir=Any_Path(self.projectName)
            )
        for test_suite in discover:
            if test_suite:
                for test_case in test_suite:
                    testsuite.addTests(test_case)
        return testsuite


class RunFailError:

    def __init__(self, classlist, class_case):
        '''
        运行错误率及失败率较高的用例
        '''
        self.classlist = classlist      #类列表
        self.class_case = class_case       #类方法列表
        self.runner = unittest.TextTestRunner(verbosity=1)

    def get_case(self,classname, funname):
        '''
        获取相应的用例
        :param all_data: 类对应的用例
        :return:
        '''
        testsuite = unittest.TestSuite()
        testsuite.addTest(classname(funname))
        return testsuite

    def run_fail_error(self):
        '''
        运行失败或者错误率达到多少的
        :return:
        '''
        global suite
        if self.classlist and self.class_case:
            for fail_error in self.class_case:
                for classname in self.classlist:
                    class_name = str(classname).split('.')[-1].split("'")[0]
                    if fail_error[0] == class_name:
                        self.runner.run(self.get_case(classname,fail_error[1]))


class GetAllFunction:
    def __init__(self, class_fun):
        '''
        运行错误率及失败率较高的用例
        '''
        self.class_fun = class_fun  # 类列表
        self.runner = unittest.TextTestRunner(verbosity=1)
        self.test_suite = unittest.TestSuite()
        self.runner = unittest.TextTestRunner()
        # self.lock = Lock()

    def run_all_case(self):
        '''
        运行所有用例
        :return:
        '''
        import time
        thread_list = []
        if self.class_fun:
            for data_info in self.class_fun:
                for class_name, case_name in data_info.items():
                    for case in case_name:
                        # self.test_suite = unittest.TestSuite()
                        self.test_suite.addTest(class_name(case))
                        thread_list.append(self.test_suite)
                        # del self.test_suite
        st = int(time.time())
        for case_info in thread_list:
            fun = Process(target=self.runner.run(case_info))
            fun.start()
        ed = int(time.time())
        # print(ed - st)

# if __name__ == '__main__':
#     from ERP.purchase.management_st import management_purchase
#     data = [{management_purchase: ['test_add_purchase', 'test_list_purchase', 'test_add_supplier', 'test_get_supplier_notrvd', 'test_get_supplier_rvd', 'test_edit_supplier', 'test_purchase_plan_detail', 'test_purchase_quantity', 'test_purchase_price', 'test_purchase_order', 'test_purchase_orderconfirm', 'test_get_purchase_list', 'test_submit_audit', 'test_tobe_reviewed', 'test_audit_pass', 'test_confirmed', 'test_logistics', 'test_goods_tobe_received', 'test_unpacking', 'test_unpack_confirmed', 'test_unpacked_list_page', 'test_inventory_from', 'test_visitor_recorder', 'test_more_goods', 'test_less_goods', 'test_less_goods_handle', 'test_more_goods_handle', 'test_moregoods_abnormal_handle', 'test_moregoods_abnormal_list', 'test_moregoods_inventory', 'test_supplier_audit', 'test_supplier_rejected_list', 'test_supplier_refuse_edit', 'test_supplier_rejected_check', 'test_supplier_delete', 'test_purchase_export', 'test_purchase_plan_export', 'test_purchase_order_export', 'test_purchase_order_abnormal_export', 'test_purchase_order_unsettle_export', 'test_purchase_order_unpacking_export', 'test_application_for_payment_export', 'test_other_platforms_export', 'test_offline_payment_export', 'test_consolidated_payments', 'test_supplier_pass', 'test_supplier_pass_data_verification', 'test_supplier_pass_list', 'test_supplier_pass_turn_page', 'test_supplier_pass_number_pieces', 'test_supplier_pass_cathistory', 'test_supplier_visitor_recorder', 'test_supplier_cat_detail', 'test_supplier_nopass_turn_page', 'test_supplier_nopass_number_pieces', 'test_supplier_rejected_turn_page', 'test_supplier_rejected_number_pieces', 'test_supplier_relationship_list', 'test_purchase_order_cancel', 'test_purchase_order_refuse', 'test_purchase_re_submit_refuse', 'test_purchase_sku_price', 'test_purchase_sku_count', 'test_purchase_arrival_time', 'test_follow_up_reasone', 'test_add_follow_up_reasone', 'test_gen_pre_purchase_batch_no', 'test_cat_log', 'test_purchase_order_remarks', 'test_purchase_order_export_contract', 'test_rebuild_purchase_plan']}]
#
#     f = GetAllFunction(data).run_all_case()
# #     runner = unittest.TextTestRunner()

#     # runner.run(f)
#     for i in f:
#         runner.run(i)
#

